package datatableaux.rules;

import java.util.Collections;
import java.util.HashSet;

import datatableaux.*;
import entities.concept.*;
import entities.*;


public class DataOrRule {

	
	private OrConcept nextExp;
	private DataCompletion dc;
	//private DataBranching br;
	
	public DataOrRule(DataCompletion dc) {
		super();
		this.dc = dc;
		//this.br = this.dc.getCurrentBranching();
	}
	
	public boolean isApplicable(Individual n){
		HashSet<Concept> unexp = new HashSet<Concept> ();
		unexp.addAll(n.getLabels());
		unexp.removeAll(n.getExpandedLabels());
		if(unexp.size()<1){
			return false;
		}
		for(Concept c : unexp){
			if(c instanceof OrConcept){
				OrConcept oc = (OrConcept) c;
				if(Collections.disjoint(n.getLabels(), oc.getConceptSet())){
					//for "c1 or c2", neither of them are in the labels
					this.nextExp = oc;
					return true;
				}
			}
		}
		return false;
	}
	
	/**
	 * apply the or-rule, and generates a set of branches for the tableau to choose from.
	 * We will use branches. see data completion.
	 * @param n
	 * @return
	 */
	public boolean applyRule(Individual n){
		boolean suc = false;
		DataBranching br = null;
		if(Collections.disjoint(n.getLabels(), this.nextExp.getConceptSet())){
			//create new branches
			br = new DataBranching(n, this.nextExp.getConceptSet());
			this.setFatherBranch(br, this.nextExp);
			suc = br.createBranch();
			//debug
			//System.err.println("Or--branch created: "+br.hashCode()+", concept: "+br.getLastChosenConcept());
			//
			if(suc){
				dc.addAsCurrentBranch(br);
			}
			n.addExpandedLabels(this.nextExp);
			if(DataBranchChanges.getRecordingStatus()){
				br.getBranchChanges().addToExpandedLabel(n, this.nextExp);
			}
		}
		return suc;
	}
	
	//given an or concept OC, decide if OC is from some branch concept
	private void setFatherBranch(DataBranching cbr, OrConcept oc) {
		DataBranching current = this.dc.getCurrentBranching();
		if(current != null && current.getBranchConcepts().contains(oc)){
			cbr.setFatherBranch(current);
			return;
		}
		for(DataBranching sbr:this.dc.getAllBranchesInPath()){
			if(sbr.getBranchConcepts().contains(oc)){
				cbr.setFatherBranch(sbr);
				break;
			}
		}
	}
	
	
	
}
